﻿using System;

namespace Slc.Core.Entity
{
    public class OQL4 : IOQL4
    {
        private OQL CurrentOQL;

        public OQL4(OQL oql)
        {
            CurrentOQL = oql;
        }
        public OQL4(EntityBase e)
        {
            CurrentOQL = new OQL(e);
        }

        protected internal void AddOrderType(string orderType)
        {
            CurrentOQL.oqlString += orderType;
        }

        public OQLOrderType OrderBy(object field)
        {
            string temp = CurrentOQL.haveOrderBy ? "," : "\r\n                 ORDER BY ";
            CurrentOQL.haveOrderBy = true;
            CurrentOQL.oqlString += temp + CurrentOQL.TakeOneStackFields().SqlFieldName;
            return new OQLOrderType(this);
        }

        public OQL4 OrderBy(object field, string orderType)
        {
            string strTemp = orderType.ToLower();
            if (strTemp != "asc" && strTemp != "desc")
                throw new FormatException("排序类型错误！");
            string temp = CurrentOQL.haveOrderBy ? "," : "\r\n                 ORDER BY ";
            CurrentOQL.haveOrderBy = true;
            CurrentOQL.oqlString += temp + CurrentOQL.TakeOneStackFields().SqlFieldName + " " + orderType;

            return this;
        }

        public OQL4 OrderBy(OQLOrder order)
        {
            string temp = CurrentOQL.haveOrderBy ? "," : "\r\n                 ORDER BY ";
            CurrentOQL.haveOrderBy = true;
            CurrentOQL.oqlString += temp + order.ToString();

            return this;
        }

        public OQL4 OrderBy(OQLOrderAction orderAct)
        {
            OQLOrder order = new OQLOrder(CurrentOQL);
            orderAct(order);
            return OrderBy(order);
        }

        public OQL4 OrderBy<T>(OQLOrderAction<T> orderAct) where T : class
        {
            OQLOrder order = new OQLOrder(CurrentOQL);
            T para = CurrentOQL.GetUsedEntity<T>();
            orderAct(order, para);
            return OrderBy(order);
        }

        /// <summary>
        /// （网友[有事M我]、[左眼]提供）根据传入的实体类的多个属性的排序信息，从而进行动态的排序；
        /// 适用于不能在OQL表达式里面直接指明排序方式的场景（比如需要从前台传入）。
        /// </summary>
        /// <param name="orderStr">排序数组，形如{"ID desc","Name asc"}</param>
        /// <returns></returns>
        public OQL4 OrderBy(string[] orderStr)
        {
            if (orderStr == null || orderStr.Length <= 0)
                return this;

            string temp = CurrentOQL.haveOrderBy ? "," : "\r\n                 ORDER BY ";
            CurrentOQL.haveOrderBy = true;

            foreach (string str in orderStr)
            {
                string[] tempArr = str.Split(' ');
                string[] orderArr = new string[2];

                string tempArr_0 = tempArr[0].Trim();
                //访问属性名称对应的属性值，得到真正的排序字段
                object Value = CurrentOQL.currEntity[tempArr_0];
                //如果要排序的属性未包含在实体类的属性定义里面，下面将出现异常
                string orderField = CurrentOQL.TakeOneStackFields().SqlFieldName;
                orderArr[0] = tempArr_0;
                if (tempArr.Length == 1)
                {
                    orderArr[1] = "ASC";
                }
                else
                {
                    if (tempArr[1].Equals("desc", StringComparison.OrdinalIgnoreCase))//非desc则全部以asc进行排列
                        orderArr[1] = "DESC";
                    else
                        orderArr[1] = "ASC";
                }

                temp = string.Format("{0} {1} {2},", temp, orderField, orderArr[1]);
            }
            CurrentOQL.oqlString += temp.TrimEnd(',');
            return this;
        }


        public OQL END
        {
            get
            {
                return CurrentOQL;
            }
        }
    }
}
